#include "key/taiic_sensor.h"
#include "../../include/isp/taiic_isp_model.h" //isp:header file
#include <string.h>
#include <assert.h>
#include <getopt.h> /* getopt_long() */
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <dlfcn.h>
#include <dirent.h>
#include <fcntl.h>
#if ISPDEMO_ENABLE_DRM
#include "drmDsp.h"
#endif
#include "../../include/isp/uAPI2/rk_aiq_user_api2_sysctl.h"
#include "../../include/isp/uAPI2/rk_aiq_user_api2_debug.h"
#include "../../include/isp/sample/sample_image_process.h"
#include "../../include/isp/rkisp_demo.h"
#include <termios.h>

#include "../../include/isp/ae_algo_demo/third_party_ae_algo.h"
#include "../../include/isp/awb_algo_demo/third_party_awbV32_algo.h" //for rv1106
#include "../../include/isp/af_algo_demo/third_party_af_algo.h"

#include "../../include/isp/sample/sample_smartIr.h"

#if ISPDEMO_ENABLE_RGA && ISPDEMO_ENABLE_DRM
#include "display.h"
#include "rga.h"
#endif
#include <list>
#include <string>
#include <algorithm>
#include "isp/fcntl-linux.h"


static struct termios oldt;

void restore_terminal_settings(void)
{
    // Apply saved settings
    tcsetattr(0, TCSANOW, &oldt);
}
//make terminal read 1 char at a time
void disable_terminal_return(void)
{
    struct termios newt;

    //save terminal settings
    tcgetattr(0, &oldt);
    //init new settings
    newt = oldt;
    //change settings
    newt.c_lflag &= ~(ICANON | ECHO);
    //apply settings
    tcsetattr(0, TCSANOW, &newt);

    //make sure settings will be restored when program ends
    atexit(restore_terminal_settings);
}

void test_update_iqfile(const demo_context_t* demo_ctx)
{
    char iqfile[IQFILE_PATH_MAX_LEN] = {0};

    printf("\nspecial an new iqfile:\n");
    strcat(iqfile, demo_ctx->iqpath);
    strcat(iqfile, "/");
    char* ret = fgets(iqfile + strlen(iqfile), IQFILE_PATH_MAX_LEN, stdin);

    char* json = strstr(iqfile, "json");

    if (!json) {
        printf("[AIQ]input is not an valide json:%s\n", iqfile);
        return;
    }

    /* fgets may add '\n' in the end of input, delete it */
    json += strlen("json");
    *json = '\0';

    printf("[AIQ] appling new iq file:%s\n", iqfile);

    rk_aiq_uapi2_sysctl_updateIq(demo_ctx->aiq_ctx, iqfile);
}


#if 0
static int set_ae_onoff(const rk_aiq_sys_ctx_t* ctx, bool onoff);
void test_imgproc(const demo_context_t* demo_ctx) {

    if (demo_ctx == NULL) {
        return;
    }

    const rk_aiq_sys_ctx_t* ctx = (const rk_aiq_sys_ctx_t*)(demo_ctx->aiq_ctx);

    /*TODO: when rkaiq_3A_server & rkisp_demo run in two different shell, rk_aiq_sys_ctx_t would be null?*/
    if (ctx == NULL) {
        printf("ERROR : rk_aiq_sys_ctx_t is null.\n");
        _if_quit = true;
        return;
    }

    int key = getchar();
    printf("press key=[%c]\n", key);

    opMode_t mode;
    paRange_t range;
    expPwrLineFreq_t freq;
    rk_aiq_wb_scene_t scene;
    rk_aiq_wb_gain_t gain;
    rk_aiq_wb_cct_t ct;
    antiFlickerMode_t flicker;
    switch (key)
    {
    case '0':
        rk_aiq_uapi_setExpMode(ctx, OP_MANUAL);
        printf("set exp manual\n");
        break;
    case '.':
        rk_aiq_uapi_setExpMode(ctx, OP_AUTO);
        printf("set exp auto\n");
        break;
    case '1':
        rk_aiq_uapi_getExpMode(ctx, &mode);
        printf("exp mode=%d\n", mode);
        break;
    case '2':
        range.min = 5.0f;
        range.max = 8.0f;
        rk_aiq_uapi_setExpGainRange(ctx, &range);
        printf("set gain range\n");
        break;
    case '3':
        rk_aiq_uapi_getExpGainRange(ctx, &range);
        printf("get gain range[%f,%f]\n", range.min, range.max);
        break;
    case '4':
        range.min = 10.0f;
        range.max = 30.0f;
        rk_aiq_uapi_setExpTimeRange(ctx, &range);
        printf("set time range\n");
        break;
    case '5':
        rk_aiq_uapi_getExpTimeRange(ctx, &range);
        printf("get time range[%f,%f]\n", range.min, range.max);
        break;
    case '6':
        rk_aiq_uapi_setExpPwrLineFreqMode(ctx, EXP_PWR_LINE_FREQ_50HZ);
        printf("setExpPwrLineFreqMode 50hz\n");
        break;
    case ',':
        rk_aiq_uapi_setExpPwrLineFreqMode(ctx, EXP_PWR_LINE_FREQ_60HZ);
        printf("setExpPwrLineFreqMode 60hz\n");
        break;
    case '7':
        rk_aiq_uapi_getExpPwrLineFreqMode(ctx, &freq);
        printf("getExpPwrLineFreqMode=%d\n", freq);
        break;
    case '8':
        rk_aiq_uapi_setWBMode(ctx, OP_MANUAL);
        printf("setWBMode manual\n");
        break;
    case '/':
        rk_aiq_uapi_setWBMode(ctx, OP_AUTO);
        printf("setWBMode auto\n");
        break;
    case '9':
        rk_aiq_uapi_getWBMode(ctx, &mode);
        printf("getWBMode=%d\n", mode);
        break;
    case 'a':
        rk_aiq_uapi_lockAWB(ctx);
        printf("lockAWB\n");
        break;
    case 'b':
        rk_aiq_uapi_unlockAWB(ctx);
        printf("unlockAWB\n");
        break;
    case 'c':
        rk_aiq_uapi_setMWBScene(ctx, RK_AIQ_WBCT_TWILIGHT);
        printf("setMWBScene\n");
        break;
    case 'd':
        rk_aiq_uapi_getMWBScene(ctx, &scene);
        printf("getMWBScene=%d\n", scene);
        break;
    case 'e':
        gain.rgain = 0.5f;
        gain.grgain = 0.5f;
        gain.gbgain = 0.5f;
        gain.bgain = 0.5f;
        rk_aiq_uapi_setMWBGain(ctx, &gain);
        printf("setMWBGain\n");
        break;
    case 'f':
        rk_aiq_uapi_getMWBGain(ctx, &gain);
        printf("getMWBGain=[%f %f %f %f]\n", gain.rgain, gain.grgain, gain.gbgain, gain.bgain);
        break;
    case 'g':
        break;
    case 'h':
        break;
    case 'i':
        rk_aiq_uapi_setAntiFlickerMode(ctx, ANTIFLICKER_NORMAL_MODE);
        printf("setAntiFlickerMode normal\n");
        break;
    case 'j':
        rk_aiq_uapi_setAntiFlickerMode(ctx, ANTIFLICKER_AUTO_MODE);
        printf("setAntiFlickerMode auto\n");
        break;
    case 'k':
        rk_aiq_uapi_getAntiFlickerMode(ctx, &flicker);
        printf("getAntiFlickerMode=%d\n", flicker);
        break;
    case 'l':
        rk_aiq_uapi_setSaturation(ctx, 50);
        printf("setSaturation\n");
        break;
    case 'm':
        unsigned int level1;
        rk_aiq_uapi_getSaturation(ctx, &level1);
        printf("getSaturation=%d\n", level1);
        break;
    case 'n':
        rk_aiq_uapi_setCrSuppsn(ctx, 50);
        printf("setCrSuppsn\n");
        break;
    case 'o':
        unsigned int level2;
        rk_aiq_uapi_getCrSuppsn(ctx, &level2);
        printf("getCrSuppsn=%d\n", level2);
        break;
    case 'p':
        //rk_aiq_uapi_setHDRMode(ctx, OP_AUTO);
        printf("setHDRMode\n");
        break;
    case 'q':
        //rk_aiq_uapi_setHDRMode(ctx, OP_MANUAL);
        printf("setHDRMode\n");
        break;
    case 'r':
        //rk_aiq_uapi_getHDRMode(ctx, &mode);
        printf("getHDRMode=%d\n", mode);
        break;
    case 's': {
        unsigned int set_anr_strength = 80;
        unsigned int get_anr_strength = 0;
        rk_aiq_uapi_setANRStrth(ctx, set_anr_strength);
        printf("setANRStrth %u \n", set_anr_strength);
        sleep(1);
        rk_aiq_uapi_getANRStrth(ctx, &get_anr_strength);
        printf("getANRStrth %u \n", get_anr_strength);
        break;
    }
    case 't': {
        unsigned int set_strength = 80;
        unsigned int get_space_strength = 0;
        unsigned int get_mfnr_strength = 0;
        bool state;
        rk_aiq_uapi_setMSpaNRStrth(ctx, true, set_strength);
        rk_aiq_uapi_setMTNRStrth(ctx, true, set_strength);
        printf("setMSpaNRStrth and setMTNRStrth :%u \n", set_strength);
        rk_aiq_uapi_getMSpaNRStrth(ctx, &state, &get_space_strength);
        rk_aiq_uapi_getMTNRStrth(ctx, &state, &get_mfnr_strength);
        printf("setMSpaNRStrth and setMTNRStrth :%u %u\n", get_space_strength, get_mfnr_strength);
        break;
    }
    case 'u':
        //rk_aiq_uapi_setDhzMode(ctx, OP_MANUAL);
        //printf("setDhzMode\n");
        break;
    case 'v':
        //rk_aiq_uapi_getDhzMode(ctx, &mode);
        // printf("getDhzMode=%d\n", mode);
        break;
    case 'w':
    {
        bool stat = false;
        //unsigned int level4 = 0;
        //rk_aiq_uapi_getMHDRStrth(ctx, &stat, &level4);
        //printf("getMHDRStrth: status:%d, level=%d\n", stat, level4);
    }
    break;
    case 'x':
        //rk_aiq_uapi_setMHDRStrth(ctx, true, 8);
        //printf("setMHDRStrth true\n");
        break;
    case 'y':
    {
        bool mod_en;
        rk_aiq_uapi2_sysctl_getModuleCtl(ctx, RK_MODULE_TNR, &mod_en);
        printf("getModuleCtl=%d\n", mod_en);
        if (mod_en) {
            rk_aiq_uapi2_sysctl_setModuleCtl(ctx, RK_MODULE_TNR, false);
        } else {
            rk_aiq_uapi2_sysctl_setModuleCtl(ctx, RK_MODULE_TNR, true);
        }
    }
    break;
    case 'z':
        rk_aiq_uapi_setFocusMode(ctx, OP_AUTO);
        printf("setFocusMode OP_AUTO\n");
        break;
    case 'A':
        rk_aiq_uapi_setFocusMode(ctx, OP_SEMI_AUTO);
        printf("setFocusMode OP_SEMI_AUTO\n");
        break;
    case 'B':
        rk_aiq_uapi_setFocusMode(ctx, OP_MANUAL);
        printf("setFocusMode OP_MANUAL\n");
        break;
    case 'C':
        rk_aiq_uapi_manualTrigerFocus(ctx);
        printf("manualTrigerFocus\n");
        break;
    case 'D': {
        rk_aiq_af_zoomrange range;
        int code;

        rk_aiq_uapi_getZoomRange(ctx, &range);
        printf("zoom.min_pos %d, zoom.max_pos %d\n", range.min_pos, range.max_pos);

        rk_aiq_uapi_getOpZoomPosition(ctx, &code);
        printf("getOpZoomPosition code %d\n", code);

        code += 20;
        if (code > range.max_pos)
            code = range.max_pos;
        rk_aiq_uapi_setOpZoomPosition(ctx, code);
        rk_aiq_uapi_endOpZoomChange(ctx);
        printf("setOpZoomPosition %d\n", code);
    }
    break;
    case 'E': {
        rk_aiq_af_zoomrange range;
        int code;

        rk_aiq_uapi_getZoomRange(ctx, &range);
        printf("zoom.min_pos %d, zoom.max_pos %d\n", range.min_pos, range.max_pos);

        rk_aiq_uapi_getOpZoomPosition(ctx, &code);
        printf("getOpZoomPosition code %d\n", code);

        code -= 20;
        if (code < range.min_pos)
            code = range.min_pos;
        rk_aiq_uapi_setOpZoomPosition(ctx, code);
        rk_aiq_uapi_endOpZoomChange(ctx);
        printf("setOpZoomPosition %d\n", code);
    }
    break;
    case 'F': {
        rk_aiq_af_focusrange range;
        short code;

        rk_aiq_uapi_getFocusRange(ctx, &range);
        printf("focus.min_pos %d, focus.max_pos %d\n", range.min_pos, range.max_pos);

        rk_aiq_uapi_getFixedModeCode(ctx, &code);

        code++;
        if (code > range.max_pos)
            code = range.max_pos;
        rk_aiq_uapi_setFixedModeCode(ctx, code);
        printf("setFixedModeCode %d\n", code);
    }
    break;
    case 'G': {
        rk_aiq_af_focusrange range;
        short code;

        rk_aiq_uapi_getFocusRange(ctx, &range);
        printf("focus.min_pos %d, focus.max_pos %d\n", range.min_pos, range.max_pos);

        rk_aiq_uapi_getFixedModeCode(ctx, &code);

        code--;
        if (code < range.min_pos)
            code = range.min_pos;
        rk_aiq_uapi_setFixedModeCode(ctx, code);
        printf("setFixedModeCode %d\n", code);
    }
    break;
    case 'H': {
        rk_aiq_af_attrib_t attr;
        uint16_t gamma_y[RKAIQ_RAWAF_GAMMA_NUM] =
        {0, 45, 108, 179, 245, 344, 409, 459, 500, 567, 622, 676, 759, 833, 896, 962, 1023};

        rk_aiq_user_api_af_GetAttrib(ctx, &attr);
        attr.manual_meascfg.contrast_af_en = 1;
        attr.manual_meascfg.rawaf_sel = 0; // normal = 0; hdr = 1

        attr.manual_meascfg.window_num = 2;
        attr.manual_meascfg.wina_h_offs = 2;
        attr.manual_meascfg.wina_v_offs = 2;
        attr.manual_meascfg.wina_h_size = 2580;
        attr.manual_meascfg.wina_v_size = 1935;

        attr.manual_meascfg.winb_h_offs = 500;
        attr.manual_meascfg.winb_v_offs = 600;
        attr.manual_meascfg.winb_h_size = 300;
        attr.manual_meascfg.winb_v_size = 300;

        attr.manual_meascfg.gamma_flt_en = 1;
        memcpy(attr.manual_meascfg.gamma_y, gamma_y, RKAIQ_RAWAF_GAMMA_NUM * sizeof(uint16_t));

        attr.manual_meascfg.gaus_flt_en = 1;
        attr.manual_meascfg.gaus_h0 = 0x20;
        attr.manual_meascfg.gaus_h1 = 0x10;
        attr.manual_meascfg.gaus_h2 = 0x08;

        attr.manual_meascfg.afm_thres = 4;

        attr.manual_meascfg.lum_var_shift[0] = 0;
        attr.manual_meascfg.afm_var_shift[0] = 0;
        attr.manual_meascfg.lum_var_shift[1] = 4;
        attr.manual_meascfg.afm_var_shift[1] = 4;

        attr.manual_meascfg.sp_meas.enable = true;
        attr.manual_meascfg.sp_meas.ldg_xl = 10;
        attr.manual_meascfg.sp_meas.ldg_yl = 28;
        attr.manual_meascfg.sp_meas.ldg_kl = (255 - 28) * 256 / 45;
        attr.manual_meascfg.sp_meas.ldg_xh = 118;
        attr.manual_meascfg.sp_meas.ldg_yh = 8;
        attr.manual_meascfg.sp_meas.ldg_kh = (255 - 8) * 256 / 15;
        attr.manual_meascfg.sp_meas.highlight_th = 245;
        attr.manual_meascfg.sp_meas.highlight2_th = 200;
        rk_aiq_user_api_af_SetAttrib(ctx, &attr);
    }
    break;
    case 'I':
        if (CHECK_ISP_HW_V20()) {
            rk_aiq_nr_IQPara_t stNRIQPara;
            rk_aiq_nr_IQPara_t stGetNRIQPara;
            stNRIQPara.module_bits = (1 << ANR_MODULE_BAYERNR) | (1 << ANR_MODULE_MFNR) | (1 << ANR_MODULE_UVNR) | (1 << ANR_MODULE_YNR);
            stGetNRIQPara.module_bits = (1 << ANR_MODULE_BAYERNR) | (1 << ANR_MODULE_MFNR) | (1 << ANR_MODULE_UVNR) | (1 << ANR_MODULE_YNR);
            rk_aiq_user_api_anr_GetIQPara(ctx, &stNRIQPara);
            for(int m = 0; m < 3; m++) {
                for(int k = 0; k < 2; k++) {
                    for(int i = 0; i < CALIBDB_NR_SHARP_MAX_ISO_LEVEL; i++ ) {
                        //bayernr
                        stNRIQPara.stBayernrPara.mode_cell[m].setting[k].filtPara[i] = 0.1;
                        stNRIQPara.stBayernrPara.mode_cell[m].setting[k].lamda = 500;
                        stNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[0][i] = 0.1;
                        stNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[1][i] = 0.1;
                        stNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[2][i] = 0.1;
                        stNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[3][i] = 0.1;

                        //mfnr
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[0] = 2;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[1] = 2;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[2] = 2;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[3] = 2;

                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[0] = 2;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[1] = 2;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[2] = 2;

                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[0] = 0.4;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[1] = 0.6;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[2] = 0.8;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[3] = 1.0;

                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[0] = 0.4;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[1] = 0.6;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[2] = 0.8;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[3] = 1.0;

                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[0] = 0.1;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[1] = 0.2;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[2] = 0.3;

                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[0] = 0.1;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[1] = 0.2;
                        stNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[2] = 0.3;

                        //ynr
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[0] = 0.4;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[1] = 0.6;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[2] = 0.8;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[3] = 1.0;

                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[0] = 0.4;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[1] = 0.6;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[2] = 0.8;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[3] = 1.0;

                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseStrength = 1.0;

                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[0] = 1.0;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[1] = 1.0;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[2] = 1.0;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[3] = 1.0;

                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[0] = 1.0;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[1] = 1.0;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[2] = 1.0;
                        stNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[3] = 1.0;

                        //uvnr
                        stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step0_uvgrad_ratio[i] = 100;
                        stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step1_median_ratio[i] = 0.5;
                        stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step2_median_ratio[i] = 0.5;
                        stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step1_bf_sigmaR[i] = 20;
                        stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step2_bf_sigmaR[i] = 16;
                        stNRIQPara.stUvnrPara.mode_cell[m].setting[k].step3_bf_sigmaR[i] = 8;

                    }
                }
            }

            rk_aiq_user_api_anr_SetIQPara(ctx, &stNRIQPara);
            sleep(5);
            //printf all the para
            rk_aiq_user_api_anr_GetIQPara(ctx, &stGetNRIQPara);

            for(int m = 0; m < 1; m++) {
                for(int k = 0; k < 1; k++) {
                    for(int i = 0; i < CALIBDB_NR_SHARP_MAX_ISO_LEVEL; i++ ) {
                        printf("\n\n!!!!!!!!!!set:%d cell:%d !!!!!!!!!!\n", k, i);
                        printf("oyyf222 bayernr: fiter:%f lamda:%f fixw:%f %f %f %f\n",
                               stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].filtPara[i],
                               stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].lamda,
                               stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[0][i],
                               stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[1][i],
                               stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[2][i],
                               stGetNRIQPara.stBayernrPara.mode_cell[m].setting[k].fixW[3][i]);

                        printf("oyyf222 mfnr: limiy:%f %f %f %f uv: %f %f %f, y_lo:%f %f %f %f y_hi:%f %f %f %f uv_lo:%f %f %f uv_hi:%f %f %f\n",
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[0],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[1],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[2],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_y[3],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[0],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[1],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].weight_limit_uv[2],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[0],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[1],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[2],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_lo_bfscale[3],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[0],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[1],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[2],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].y_hi_bfscale[3],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[0],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[1],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_lo_bfscale[2],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[0],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[1],
                               stGetNRIQPara.stMfnrPara.mode_cell[m].setting[k].mfnr_iso[i].uv_hi_bfscale[2]);

                        printf("oyyf222 ynr: lo_bf:%f %f %f %f  lo_do:%f %f %f %f  hi_bf:%f %f %f %f stre:%f hi_do:%f %f %f %f\n",
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[0],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[1],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[2],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].lo_bfScale[3],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[0],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[1],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[2],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].denoise_weight[3],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[0],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[1],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[2],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_bfScale[3],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseStrength,
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[0],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[1],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[2],
                               stGetNRIQPara.stYnrPara.mode_cell[m].setting[k].ynr_iso[i].hi_denoiseWeight[3]
                              );

                        printf("oyyf222 uvnr: uv:%f  med:%f %f sigmaR:%f %f %f\n",
                               stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step0_uvgrad_ratio[i],
                               stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step1_median_ratio[i],
                               stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step2_median_ratio[i],
                               stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step1_bf_sigmaR[i],
                               stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step2_bf_sigmaR[i],
                               stGetNRIQPara.stUvnrPara.mode_cell[m].setting[k].step3_bf_sigmaR[i]);

                        printf("!!!!!!!!!!set:%d cell:%d  end !!!!!!!!!!\n\n", k, i);
                    }
                }
            }
        }
        break;
    case 'J':
        if (CHECK_ISP_HW_V20()) {
            rk_aiq_sharp_IQpara_t stSharpIQpara;
            rk_aiq_sharp_IQpara_t stGetSharpIQpara;
            stSharpIQpara.module_bits = (1 << ASHARP_MODULE_SHARP) | (1 << ASHARP_MODULE_EDGEFILTER) ;
            rk_aiq_user_api_asharp_GetIQPara(ctx, &stSharpIQpara);
            for(int m = 0; m < 3; m++) {
                for(int k = 0; k < 2; k++) {
                    for(int i = 0; i < CALIBDB_NR_SHARP_MAX_ISO_LEVEL; i++ ) {
                        stSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].hratio = 1.9;
                        stSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].lratio = 0.4;
                        stSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].mf_sharp_ratio = 5.0;
                        stSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].hf_sharp_ratio = 6.0;

                        stSharpIQpara.stEdgeFltPara.mode_cell[m].setting[k].edgeFilter_iso[i].edge_thed = 33.0;
                        stSharpIQpara.stEdgeFltPara.mode_cell[m].setting[k].edgeFilter_iso[i].local_alpha = 0.5;
                    }
                }
            }
            rk_aiq_user_api_asharp_SetIQPara(ctx, &stSharpIQpara);
            sleep(5);
            rk_aiq_user_api_asharp_GetIQPara(ctx, &stGetSharpIQpara);
            for(int m = 0; m < 1; m++) {
                for(int k = 0; k < 1; k++) {
                    for(int i = 0; i < CALIBDB_NR_SHARP_MAX_ISO_LEVEL; i++ ) {
                        printf("\n\n!!!!!!!!!!set:%d cell:%d !!!!!!!!!!\n", k, i);
                        printf("oyyf222 sharp:%f %f ratio:%f %f\n",
                               stGetSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].lratio,
                               stGetSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].hratio,
                               stGetSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].mf_sharp_ratio,
                               stGetSharpIQpara.stSharpPara.mode_cell[m].setting[k].sharp_iso[i].hf_sharp_ratio);

                        printf("oyyf222 edgefilter:%f %f\n",
                               stGetSharpIQpara.stEdgeFltPara.mode_cell[m].setting[k].edgeFilter_iso[i].edge_thed,
                               stGetSharpIQpara.stEdgeFltPara.mode_cell[m].setting[k].edgeFilter_iso[i].local_alpha);

                        printf("!!!!!!!!!!set:%d cell:%d  end !!!!!!!!!!\n", k, i);
                    }
                }
            }
        }
        break;
    case 'K':
        printf("test mirro, flip\n");
        bool mirror, flip;
        rk_aiq_uapi_getMirrorFlip(ctx, &mirror, &flip);
        printf("oringinal mir %d, flip %d \n", mirror, flip);
        mirror = true;
        flip = true;
        printf("set mir %d, flip %d \n", mirror, flip);
        rk_aiq_uapi_setMirroFlip(ctx, true, true, 3);
        rk_aiq_uapi_getMirrorFlip(ctx, &mirror, &flip);
        printf("after set mir %d, flip %d \n", mirror, flip);
        break;
    case 'L':
        printf("test fec correct level100\n");
        rk_aiq_uapi_setFecCorrectLevel(ctx, 100);
        break;
    case 'M':
        printf("test fec correct level255\n");
        rk_aiq_uapi_setFecCorrectLevel(ctx, 255);
        break;
    case 'N':
    {
        rk_aiq_dpcc_attrib_V20_t attr;
        rk_aiq_user_api2_adpcc_GetAttrib(ctx, &attr);
        rk_aiq_user_api2_adpcc_SetAttrib(ctx, &attr);
        adebayer_attrib_t attr2;
        rk_aiq_user_api2_adebayer_SetAttrib(ctx, attr2);
    }
    break;
    case 'O':
        printf("test not bypass fec\n");
        rk_aiq_uapi_setFecBypass(ctx, false);
        break;
    case 'P':
    {
        int work_mode = demo_ctx->hdrmode;
        rk_aiq_working_mode_t new_mode;
        if (work_mode == RK_AIQ_WORKING_MODE_NORMAL)
            new_mode = RK_AIQ_WORKING_MODE_ISP_HDR3;
        else
            new_mode = RK_AIQ_WORKING_MODE_NORMAL;
        printf("switch work mode from %d to %d\n", work_mode, new_mode);
        *const_cast<int*>(&demo_ctx->hdrmode) = work_mode = new_mode;
        rk_aiq_uapi_sysctl_swWorkingModeDyn(ctx, new_mode);
    }
    break;
    case 'Q':
    {
        rk_aiq_rotation_t rot = RK_AIQ_ROTATION_90;
        rk_aiq_mems_sensor_intf_t intf = {0};
        const char* main_scene = "good";
        const char* sub_scene = "bad";
        rk_aiq_uapi2_sysctl_setSharpFbcRotation(ctx, rot);
        rk_aiq_uapi2_sysctl_setMulCamConc(ctx, true);
        rk_aiq_uapi2_sysctl_regMemsSensorIntf(ctx, &intf);
        rk_aiq_uapi2_sysctl_switch_scene(ctx, main_scene, sub_scene);
    }
    break;
    case 'R':
    {
        rk_aiq_cpsl_info_t cpsl_info;
        rk_aiq_cpsl_cap_t cpsl_cap;
        rk_aiq_uapi2_sysctl_getCpsLtInfo(ctx, &cpsl_info);
        rk_aiq_uapi2_sysctl_queryCpsLtCap(ctx, &cpsl_cap);
        printf("sensitivity: %f, cap sensitivity: %f:%f:%f\n", cpsl_info.sensitivity,
               cpsl_cap.sensitivity.min, cpsl_cap.sensitivity.step, cpsl_cap.sensitivity.max);
        rk_aiq_cpsl_cfg_t cpsl_cfg;
        rk_aiq_uapi2_sysctl_setCpsLtCfg(ctx, &cpsl_cfg);
    }
    break;
    case 'S':
        printf("test ldch correct level100\n");
        rk_aiq_uapi_setLdchCorrectLevel(ctx, 100);
        break;
    case 'T':
    {
        rk_aiq_rect_t info;
        rk_aiq_uapi2_sysctl_getCrop(ctx, &info);
        printf("left:%d, top:%d, width:%d, height:%d\n", info.left, info.top, info.width, info.height);
        info.left += 64;
        info.top += 64;
        info.width = 640;
        info.height = 480;
        //rk_aiq_uapi2_sysctl_setCrop(ctx, info);
    }
    break;
    case 'U':
    {
        char output_dir[64] = {0};
        printf("test to capture raw sync\n");
        rk_aiq_uapi_debug_captureRawSync(ctx, CAPTURE_RAW_SYNC, 5, "/tmp", output_dir);
        printf("Raw's storage directory is (%s)\n", output_dir);
    }
    break;
    case 'V':
    {
        test_update_iqfile(demo_ctx);
    }
    break;
    case 'W':
    {
        rk_aiq_ver_info_t vers;
        rk_aiq_uapi2_get_version_info(&vers);
        printf("aiq ver %s, parser ver %s, magic code %d, awb ver %s\n"
               "ae ver %s, af ver %s, ahdr ver %s\n", vers.aiq_ver,
               vers.iq_parser_ver, vers.iq_parser_magic_code,
               vers.awb_algo_ver, vers.ae_algo_ver,
               vers.af_algo_ver, vers.ahdr_algo_ver);
    }
    break;
    case 'X':
    {
        for (int type = RK_AIQ_ALGO_TYPE_AE; type < RK_AIQ_ALGO_TYPE_MAX; type++)
        {
            bool ret = rk_aiq_uapi2_sysctl_getAxlibStatus(ctx, type, 0);
            printf("%d is %s, \n", type, (ret ? "enabled" : "disabled or unregistered"));

            const RkAiqAlgoContext* algo_ptr = rk_aiq_uapi2_sysctl_getEnabledAxlibCtx(ctx, type);
            if (algo_ptr) {
                printf("type: %d ==> algo_ptr: %p\n", type, algo_ptr);
            }
            if (ret == false) {
                bool ret2 = rk_aiq_uapi2_sysctl_enableAxlib(ctx, type, 0, !ret);
            }
        }
    }
    break;
    case 'Y':
    {
        rk_aiq_lsc_querry_info_t info;
        rk_aiq_user_api2_alsc_QueryLscInfo(ctx, &info);
        printf("LSC: enable: %s, \n", (info.lsc_en ? "true" : "false"));
        printf("r: %d, %d, %d \n", info.r_data_tbl[0], info.r_data_tbl[1], info.r_data_tbl[2]);
        printf("gr: %d, %d, %d \n", info.gr_data_tbl[0], info.gr_data_tbl[1], info.gr_data_tbl[2]);
        printf("gb: %d, %d, %d \n", info.gb_data_tbl[0], info.gb_data_tbl[1], info.gb_data_tbl[2]);
        printf("b: %d, %d, %d \n", info.b_data_tbl[0], info.b_data_tbl[1], info.b_data_tbl[2]);
    }
    break;
    case 'Z':
    {
        rk_aiq_static_info_t info;
        rk_aiq_uapi2_sysctl_enumStaticMetas(0, &info);
        printf("isp version: %d, sensor name: %s\n", info.isp_hw_ver, info.sensor_info.sensor_name);
    }
    case '[':
        set_ae_onoff(ctx, true);
        printf("set ae on\n");
        break;
    case ']':
        set_ae_onoff(ctx, false);
        printf("set ae off\n");
        break;
    default:
        break;
    }
}
#endif

int xioctl(int fh, int request, void *arg)
{
    int r;
    do {
        r = ioctl(fh, request, arg);
    } while (-1 == r && EINTR == errno);
    return r;
}

void flush_and_sync(FILE *fp) 
{
  fflush(fp);
  fsync(fileno(fp));
}

#if 0
static int set_ae_onoff(const rk_aiq_sys_ctx_t* ctx, bool onoff)
{
    XCamReturn ret = XCAM_RETURN_NO_ERROR;
    Uapi_ExpSwAttr_t expSwAttr;

    ret = rk_aiq_user_api_ae_getExpSwAttr(ctx, &expSwAttr);
    expSwAttr.enable = onoff;
    ret = rk_aiq_user_api_ae_setExpSwAttr(ctx, expSwAttr);

    return 0;
}
#endif

static void print_af_stats(rk_aiq_isp_stats_t *stats_ref)
{
    unsigned long sof_time;

    if (stats_ref->frame_id % 30 != 0)
        return;

    sof_time = stats_ref->af_stats.sof_tim / 1000000LL;
    printf("sof_tim %ld, sharpness roia: 0x%llx-0x%08x roib: 0x%x-0x%08x\n",
           sof_time,
           stats_ref->af_stats.roia_sharpness,
           stats_ref->af_stats.roia_luminance,
           stats_ref->af_stats.roib_sharpness,
           stats_ref->af_stats.roib_luminance);

    printf("global_sharpness\n");
    for (int i = 0; i < 15; i++)
    {
        for (int j = 0; j < 15; j++)
        {
            printf("0x%08x, ", stats_ref->af_stats.global_sharpness[15 * i + j]);
        }
        printf("\n");
    }
    printf("lowpass_fv4_4\n");
    for (int i = 0; i < 15; i++)
    {
        for (int j = 0; j < 15; j++)
        {
            printf("0x%08x, ", stats_ref->af_stats.lowpass_fv4_4[15 * i + j]);
        }
        printf("\n");
    }
    printf("lowpass_fv8_8\n");
    for (int i = 0; i < 15; i++)
    {
        for (int j = 0; j < 15; j++)
        {
            printf("0x%08x, ", stats_ref->af_stats.lowpass_fv8_8[15 * i + j]);
        }
        printf("\n");
    }
    printf("lowpass_highlht\n");
    for (int i = 0; i < 15; i++)
    {
        for (int j = 0; j < 15; j++)
        {
            printf("0x%08x, ", stats_ref->af_stats.lowpass_highlht[15 * i + j]);
        }
        printf("\n");
    }
    printf("lowpass_highlht2\n");
    for (int i = 0; i < 15; i++)
    {
        for (int j = 0; j < 15; j++)
        {
            printf("0x%08x, ", stats_ref->af_stats.lowpass_highlht2[15 * i + j]);
        }
        printf("\n");
    }
}

























